package com.example.demo.photoFile.service;

import com.example.demo.easyexcel.db.repository.CityRepository;
import com.example.demo.util.PicUtils;
import com.example.demo.util.ResultUtil;
import com.example.demo.zip.test.ZipUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.Stream;

/**
 * @Author: zjq
 * @Date: create in 2022/3/18 16:24
 */
@Service
public class FileServiceImpl implements FileService {

    /**
     * 时间格式化
     */
    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd/");

    /**
     * 图片保存路径，自动从yml文件中获取数据
     * 示例： D:/home-backend/images/
     */
    @Value("${file-save-path}")
    private String fileSavePath;

    /**
     * 待上传的图片路径，自动从yml文件中获取数据
     */
    @Value("${img-path}")
    private String filePath;

    @Autowired
    private CityRepository cityRepository;

    final Logger log = LoggerFactory.getLogger(getClass());

    //文件大小
    public static Float getsize(MultipartFile file) {
        // 首先先将.getSize()获取的Long转为String 然后将String转为Float并除以1024 （因为1KB=1024B）这里是MB
        Float size = Float.parseFloat(String.valueOf(file.getSize())) / 1024 / 1024;
        BigDecimal b = new BigDecimal(size);
        // 2表示2位 ROUND_HALF_UP表明四舍五入，
        size = b.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
        // 此时size就是保留两位小数的浮点数
        return size;
    }

    @Override
    public Map<String, Object> uploadPhoto(MultipartFile file, HttpServletRequest request) {
        //1.后半段目录：  2020/03/15
        String directory = simpleDateFormat.format(new Date());
        //如果目录不存在，则创建
        File dir = new File(fileSavePath + directory);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        //2.文件保存目录      图片上传，保存位置： D:/file-backend/images/2020/03/15/
        System.out.println("图片上传，保存位置：" + fileSavePath + directory);

        try {
            //判断文件大小---
            if (getsize(file) > 5) {
                System.out.println("文件大于5M");
                String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
                String newFileName = UUID.randomUUID().toString().replaceAll("-", "") + suffix;

                byte[] bytes = PicUtils.compressPicForScale(file.getBytes(), 1024 * 5);
                ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);

                BufferedImage image = ImageIO.read(inputStream);
                //将in作为输入流，读取图片存入image中，而这里in可以为ByteArrayInputStream();
                ImageIO.write(image, "jpg", new File(fileSavePath + directory + newFileName));

                String url = request.getContextPath() + "/images/" + directory + newFileName;
                System.out.println("图片上传大于5M，访问URL：" + url);
                return ResultUtil.success("filePath", url);
            } else {
                //3.给文件重新设置一个名字
                //后缀
                String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
                String newFileName = UUID.randomUUID().toString().replaceAll("-", "") + suffix;
                //4.创建这个新文件
                File newFile = new File(fileSavePath + directory + newFileName);
                file.transferTo(newFile);
                //协议 :// ip地址 ：端口号 / 文件目录(/images/2020/03/15/xxx.jpg)
                //String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/images/" + directory + newFileName;
                // / 文件目录(/images/2020/03/15/xxx.jpg)
                String url = request.getContextPath() + "/images/" + directory + newFileName;
                System.out.println("图片上传，访问URL：" + url);
                return ResultUtil.success("filePath", url);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error();
        }
    }

    @Override
    public Map<String, Object> uploadPhotos(MultipartFile[] files, HttpServletRequest request) {
        Long start = System.currentTimeMillis();

        //1.后半段目录：  2020/03/15
        String directory = simpleDateFormat.format(new Date());
        //如果目录不存在，则创建
        File dir = new File(fileSavePath + directory);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        //2.文件保存目录      图片上传，保存位置： D:/file-backend/images/2020/03/15/
        try {
            String url = "";
            String obj = "";//图片路径
            List<String> photourl = new ArrayList<>();//合并的url

            //多线程速度快 ---4为核数
            ForkJoinPool pool = new ForkJoinPool(Math.min(4, files.length));

            //for (int i = 0; i < files.length; i++) {
            //    MultipartFile file = files[i];
            //    if (getsize(file) > 10) {
            //        return ResultUtil.info(-1, "照片不能大于10M");
            //    }
            //}

            ForkJoinTask<?> result = pool.submit(() -> {
                Stream.of(files).parallel().forEach(file -> {
                    try {
                        photourl.add(readPhoto(file, obj, directory, request));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
            });
            while (true) {
                if (result.isDone()) {
                    pool.shutdown();
                    break;
                }
            }
            String[] strs = photourl.toArray(new String[photourl.size()]);
            url = String.join(",", strs);

            Long end = System.currentTimeMillis();
            log.info("=====图片上传完成====={}", end - start);
            return ResultUtil.success("filePath", url);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error();
        }

    }

    public String readPhoto(MultipartFile file, String obj, String directory, HttpServletRequest
            request) throws IOException {
        //判断文件大小---
        if (getsize(file) > 1) {
            String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            String newFileName = UUID.randomUUID().toString().replaceAll("-", "") + suffix;

            byte[] bytes = PicUtils.compressPicForScale(file.getBytes(), 1024 * 1);
            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);

            BufferedImage image = ImageIO.read(inputStream);
            //将in作为输入流，读取图片存入image中，而这里in可以为ByteArrayInputStream();
            ImageIO.write(image, "jpg", new File(fileSavePath + directory + newFileName));

            obj = request.getContextPath() + "/images/" + directory + newFileName;
        } else {
            //3.给文件重新设置一个名字
            //后缀
            String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            String newFileName = UUID.randomUUID().toString().replaceAll("-", "") + suffix;
            //4.创建这个新文件
            File newFile = new File(fileSavePath + directory + newFileName);
            file.transferTo(newFile);
            //协议 :// ip地址 ：端口号 / 文件目录(/images/2020/03/15/xxx.jpg)
            //String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/images/" + directory + newFileName;
            // / 文件目录(/images/2020/03/15/xxx.jpg)
            obj = request.getContextPath() + "/images/" + directory + newFileName;
        }
        return obj;
    }

    @Override
    public Map<String, Object> uploadPhotoFile(MultipartFile file, HttpServletRequest request) {
        String tmp = filePath + "img/";//照片保存路径
        System.out.println("上传文件前缀====" + tmp);
        try {
            //1.把压缩包保存至服务器
            File savedFile = new File(tmp, file.getOriginalFilename());
            file.transferTo(savedFile);

            //2.读取压缩包中的文件名称
            Map<String, Object> map = ZipUtil.readZipFile(tmp + file.getOriginalFilename());
            if (!"0".equals(map.get("code") + "")) {
                savedFile.delete();
                return map;
            }
            List<String> nameList = (List<String>) map.get("data");
            System.out.println(nameList);

            //3.解压压缩包
            ZipUtil.unZip(tmp + file.getOriginalFilename(), tmp);
            // 删除压缩包
            savedFile.delete();

            //这里可以是多线程--保存
            if (CollectionUtils.isNotEmpty(nameList)) {
                //多线程速度快 ---4为核数
                ForkJoinPool pool = new ForkJoinPool(Math.min(4, nameList.size()));
                ForkJoinTask<?> result = pool.submit(() ->
                        nameList.parallelStream().forEach(obj -> {
                            String strid = obj.substring(0, 1);
                            cityRepository.updatePhoto(obj, Integer.valueOf(strid));
                        })
                );
                while (true) {
                    if (result.isDone()) {
                        pool.shutdown();
                        break;
                    }
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        return ResultUtil.success();
    }

    //private void updatePhoto(List<String> nameList) {
    //
    //    String obj = nameList.get(i);
    //    //前面一部分的名称
    //    String stid = obj.substring(0, 1);
    //
    //    System.out.println("照片名称" + obj);
    //    System.out.println("照片序号" + stid);
    //
    //    cityRepository.updatePhoto(obj, Integer.valueOf(stid));
    //}

}
